package com.wu.pmo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wu.pmo.dto.*;
import com.wu.pmo.entity.*;
import com.wu.pmo.mapper.*;
import com.wu.pmo.service.ProjectsService;
import com.wu.pmo.dto.ProjectListDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class ProjectsServiceImpl extends ServiceImpl<ProjectsMapper, Projects> implements ProjectsService {


    @Autowired private CustomersMapper customersMapper;
    @Autowired private EmployeesMapper employeesMapper;
    @Autowired private WorkPackagesMapper workPackagesMapper;
    @Autowired private ClientContactsMapper clientContactsMapper;
    @Autowired private ProjectsMapper projectsMapper;

    @Override
    @Transactional
    public Projects createProject(ProjectRequestDTO dto) {

        //创建客户
        Customers customers = findOrCreateCustomer(dto.getCustomer());
        //创建销售人员
        Integer salesId = findOrCreateEmployeeAndGetId(dto.getSalesName());
        //主售人员
        Integer mainPresalesId = findOrCreateEmployeeAndGetId(dto.getMainPresalesName());
        //辅售人员
        Integer auxPresalesId = findOrCreateEmployeeAndGetId(dto.getAuxPresalesName());
        //创建项目
        Projects project = new Projects();
        BeanUtils.copyProperties(dto, project);
        project.setCustomerId(customers.getId());
        project.setSalesId(salesId);
        project.setMainPresalesId(mainPresalesId);
        project.setAuxPresalesId(auxPresalesId);
        //保存
        this.save(project);
        saveWorkPackages(project.getId(), dto.getWorkPackages());
        saveClientContacts(project.getId(), dto.getClientContacts());
        //返回
        return project;
    }

    @Override
    public List<ProjectListDTO> getProjectList() {
        return projectsMapper.selectProjectList();
    }

    @Override
    @Transactional
    public void logicalDeleteProject(Integer projectId) {
        this.removeById(projectId);
    }

    @Override
    @Transactional
    public void physicalDeleteProject(Integer projectId) {

        // 手动删除子表记录。
        workPackagesMapper.delete(new QueryWrapper<WorkPackages>().eq("project_id", projectId));
        clientContactsMapper.delete(new QueryWrapper<ClientContacts>().eq("project_id", projectId));
        
        // 最后物理删除主项目
        projectsMapper.physicalDeleteById(projectId);
    }

    @Override
    public ProjectRequestDTO getProjectDetailsById(Integer projectId) {
        Projects project = this.getById(projectId);
        if(project==null){
            throw new IllegalArgumentException("项目不存在");
        }
        ProjectRequestDTO dto = new ProjectRequestDTO();
        BeanUtils.copyProperties(project, dto);

        // 1. 获取客户信息加到表格中
        if (project.getCustomerId() != null) {
            Customers customer = customersMapper.selectById(project.getCustomerId());
            if (customer != null) {
                CustomerDTO customerDTO = new CustomerDTO();
                customerDTO.setName(customer.getName());
                customerDTO.setCategory(customer.getCategory());
                dto.setCustomer(customerDTO);
            }
        }
        
        // 2. 获取售卖人员信息加到表格中
        dto.setSalesName(getEmployeeNameById(project.getSalesId()));
        dto.setMainPresalesName(getEmployeeNameById(project.getMainPresalesId()));
        dto.setAuxPresalesName(getEmployeeNameById(project.getAuxPresalesId()));

        // 3. 获取联系人信息加到表格中
        List<ClientContacts> contacts = clientContactsMapper.selectList(new QueryWrapper<ClientContacts>().eq("project_id", projectId));
        List<ClientContactDTO> contactDTOs = contacts.stream().map(c -> {
            ClientContactDTO contactDTO = new ClientContactDTO();
            BeanUtils.copyProperties(c, contactDTO);
            return contactDTO;
        }).collect(java.util.stream.Collectors.toList());
        dto.setClientContacts(contactDTOs);

        // 4. 获取工作包信息加到表格中
        List<WorkPackages> workPackages = workPackagesMapper.selectList(new QueryWrapper<WorkPackages>().eq("project_id", projectId));
        List<WorkPackageDTO> workPackageDTOs = workPackages.stream().map(wp -> {
            WorkPackageDTO wpDto = new WorkPackageDTO();
            BeanUtils.copyProperties(wp, wpDto);
            wpDto.setEstimatorName(getEmployeeNameById(wp.getEstimatorId()));
            return wpDto;
        }).collect(java.util.stream.Collectors.toList());
        dto.setWorkPackages(workPackageDTOs);

        return dto;
    }

    @Override
    @Transactional
    public Projects updateProject(ProjectRequestDTO dto) {
        // 检查项目是否存在
        Integer projectId = dto.getId();
        if (projectId == null || this.getById(projectId) == null) {
            throw new IllegalArgumentException("需要更新的项目不存在！");
        }

        // 更新顾客和员工信息
        Customers customer = findOrCreateCustomer(dto.getCustomer());
        Integer salesId = findOrCreateEmployeeAndGetId(dto.getSalesName());
        Integer mainPresalesId = findOrCreateEmployeeAndGetId(dto.getMainPresalesName());
        Integer auxPresalesId = findOrCreateEmployeeAndGetId(dto.getAuxPresalesName());

        // 更新项目主表
        Projects projectToUpdate = new Projects();
        BeanUtils.copyProperties(dto, projectToUpdate);
        projectToUpdate.setCustomerId(customer.getId());
        projectToUpdate.setSalesId(salesId);
        projectToUpdate.setMainPresalesId(mainPresalesId);
        projectToUpdate.setAuxPresalesId(auxPresalesId);
        this.updateById(projectToUpdate);

        // 删除旧的工作包和联系人
        workPackagesMapper.delete(new QueryWrapper<WorkPackages>().eq("project_id", projectId));
        clientContactsMapper.delete(new QueryWrapper<ClientContacts>().eq("project_id", projectId));
        
        // 保存新的工作包和联系人
        saveWorkPackages(projectId, dto.getWorkPackages());
        saveClientContacts(projectId, dto.getClientContacts());

        return projectToUpdate;
    }

    // 根据ID获取员工姓名
    private String getEmployeeNameById(Integer employeeId) {
        if (employeeId == null) return null;
        Employees employee = employeesMapper.selectById(employeeId);
        return employee != null ? employee.getName() : null;
    }

    //创建客户
    private Customers findOrCreateCustomer(CustomerDTO customer) {
        if (customer==null||!StringUtils.hasText(customer.getName())){
            throw new IllegalArgumentException("客户信息不能为空");
        }
        QueryWrapper<Customers> wrapper = new QueryWrapper<>();
        wrapper.eq("name",customer.getName()).last("limit 1");
        Customers oneCustomer = customersMapper.selectOne(wrapper);
        if (oneCustomer==null){
            oneCustomer = new Customers();
            oneCustomer.setName(customer.getName());
            customersMapper.insert(oneCustomer);
        }
        return oneCustomer;
    }

    //创建客户联系人
    private void saveClientContacts(Integer id, List<ClientContactDTO> clientContacts) {
        if (clientContacts==null||clientContacts.isEmpty()){
            return;
        }
        for (ClientContactDTO clientContact : clientContacts) {
            ClientContacts cc = new ClientContacts();
            BeanUtils.copyProperties(clientContact, cc);
            cc.setProjectId(id);
            clientContactsMapper.insert(cc);
        }
    }

    //创建工作包
    private void saveWorkPackages(Integer id, List<WorkPackageDTO> workPackage) {
        if (workPackage==null||workPackage.isEmpty()){
            return;
        }
        for (WorkPackageDTO workPackageDTO : workPackage) {
            WorkPackages wp = new WorkPackages();
            BeanUtils.copyProperties(workPackageDTO, wp);
            wp.setProjectId(id);
            wp.setEstimatorId(findOrCreateEmployeeAndGetId(workPackageDTO.getEstimatorName()));
            workPackagesMapper.insert(wp);
        }
    }

    //创建员工
    private Integer findOrCreateEmployeeAndGetId(String mainPresalesName) {
        if (!StringUtils.hasText(mainPresalesName)){
            return null;
        }
        QueryWrapper<Employees> wrapper = new QueryWrapper<>();
        wrapper.eq("name",mainPresalesName).last("limit 1");
        Employees oneEmployee = employeesMapper.selectOne(wrapper);
        if (oneEmployee==null){
            oneEmployee = new Employees();
            oneEmployee.setName(mainPresalesName);
            employeesMapper.insert(oneEmployee);
        }
        return oneEmployee.getId();

    }
}




